package scaladuct

import org.objectweb.asm._

/**
 * <p>
 * Created by IntelliJ IDEA.
 * User: zslajchrt
 * Date: Aug 14, 2010
 * Time: 3:19:03 PM
 */

class CopyAnnotationsVisitor(getterIndex: Int,
                              getterVisitor: MethodVisitor,
                              methodName: String,
                              refMotherClass: Class[_], refMotherMethod: String, refMotherArg: Int,
                              isRefCollection: Boolean) extends ClassAdapter(new EmptyVisitor) {
  var phaseMethodVisited: Boolean = false
  var superClassName: String = null

  override def visit(version: Int, access: Int, name: String, signature: String, superName: String, interfaces: Array[String]): Unit = {
    super.visit(version, access, name, signature, superName, interfaces)
    superClassName = superName
  }

  override def visitMethod(access: Int, name: String, desc: String, signature: String, exceptions: Array[String]): MethodVisitor = {
    if (name == methodName) {
      val methodVisitor = super.visitMethod(access, name, desc, signature, exceptions)
      phaseMethodVisited = true
      new MethodAdapter(methodVisitor) {
        override def visitParameterAnnotation(parameter: Int, desc: String, visible: Boolean): AnnotationVisitor = {
          if (parameter != getterIndex) {
            super.visitParameterAnnotation(parameter, desc, visible)
          } else {
            val annotationVisitor = getterVisitor.visitAnnotation(desc, visible)
            if (desc == "Lscaladuct/Ref;") {
              generateRefType(annotationVisitor)
            }
            annotationVisitor
          }
        }
      }
    } else {
      super.visitMethod(access, name, desc, signature, exceptions);
    }
  }

  def generateRefType(annotationVisitor: AnnotationVisitor): Unit = {
    annotationVisitor.visit("motherClass", Type.getType(refMotherClass))
    annotationVisitor.visit("motherMethod", refMotherMethod)
    annotationVisitor.visit("motherArg", refMotherArg)
    annotationVisitor.visit("col", isRefCollection)
  }

}